package com.seaboxdata.scheduler;

import com.seaboxdata.entity.AccessJob;
import com.seaboxdata.entity.JobExcuteResult;
import com.seaboxdata.entity.SchedulerJob;
import com.seaboxdata.entity.SmsReceiverConfig;
import com.seaboxdata.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author
 * @create 2021-02-07 14:34
 **/
@Component
@Configuration
@Slf4j
public class JobMonitorJob {

    @Autowired
    private AccessJobService accessJobService;

    @Autowired
    private SchedulerJobService schedulerJobService;

    @Autowired
    private QzjAccessJobService qzjAccessJobService;

    @Autowired
    private JobExcuteResultService jobExcuteResultService;

    @Autowired
    private JobSmsReceiverConfigService jobSmsReceiverConfigService;

    @Autowired
    private SmsService smsService;

    @Value("${isSmsMonitor}")
    private String isSmsMonitor;

    @Scheduled(cron = "${job.DataMonitor}")
    public void doCollect() {
        if("true".equals(isSmsMonitor)){
            return;
        }
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = null;
        Date endDate = null;
        String dateStr = sdf.format(date);
        try {
            beginDate = sdf.parse(dateStr);
            endDate = DateUtils.addDays(beginDate, 1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //获取所有的今天调度信息

        List<AccessJob> jobs = accessJobService.getAllAccess(beginDate, endDate);
        //获取所有的调度信息
        List<SchedulerJob> allSchedulerJob = schedulerJobService.getAllSchedulerJob(beginDate, endDate);
        //获取前置机所有的接入调度信息
        List<AccessJob> qzjAccess = qzjAccessJobService.getAllAccess(beginDate, endDate);
        List<JobExcuteResult> results = new ArrayList<>();
        if (!jobs.isEmpty()) {
            packageJobExcuteResult(jobs, "51接入系统", dateStr, results);
        }

        if (!CollectionUtils.isEmpty(qzjAccess)) {
            packageJobExcuteResult(qzjAccess, "前置机接入系统", dateStr, results);
        }

        if (!CollectionUtils.isEmpty(allSchedulerJob)) {
            for (SchedulerJob schedulerJob : allSchedulerJob) {
                JobExcuteResult jobExcuteResult = new JobExcuteResult();
                jobExcuteResult.setDataDate(sdf.format(date));
                jobExcuteResult.setJobType("调度系统");
                jobExcuteResult.setExcuteStartTime(schedulerJob.getLastStartTime());
                jobExcuteResult.setExcuteEndTime(schedulerJob.getLastStartTime());
                jobExcuteResult.setJobName(schedulerJob.getEtlJob());
                switch (schedulerJob.getLastJobStatus()) {
                    case "Done": {
                        jobExcuteResult.setExcuteStatus("完成");
                    }
                    break;
                    case "Ready": {
                        jobExcuteResult.setExcuteStatus("准备");
                    }
                    break;
                    case "Failed": {
                        jobExcuteResult.setExcuteStatus("失败");
                    }
                    break;
                    default: {
                        jobExcuteResult.setExcuteStatus("pending");
                    }
                }
                results.add(jobExcuteResult);
            }
        }

        //获取所有异常的任务入库,并且发送告警短信
        if (!CollectionUtils.isEmpty(results)) {
            jobExcuteResultService.saveBatch(results);
            //发送短信
            List<SmsReceiverConfig> effectiveReceiver = jobSmsReceiverConfigService.getEffectiveReceiver(date);
            //组装短信,发送短信
            String msg = null;
            StringBuilder sb = new StringBuilder();
            for (JobExcuteResult result : results) {
                sb.append(result.getJobType()).append(":");
                if (result.getJobName() == null) {
                    sb.append("数据源名称:").append(result.getSrcDataName()).append(",").
                            append("目标源名称:").append(result.getTargetDataName()).append(",").
                            append("执行开始时间:").append(result.getExcuteStartTime().toLocaleString()).append(",").
                            append("执行状态:").append(result.getExcuteStatus()).append(",")
                            .append("任务组id").append(result.getTaskId()).append(",");
                } else {
                    sb.append("任务名称:").append(result.getJobName()).append(",").
                            append("执行开始时间:").append(result.getExcuteStartTime().toLocaleString()).append(",").
                            append("执行状态:").append(result.getExcuteStatus()).append(",");
                }
            }
            msg = sb.toString();
            if(msg.length() >= 300){
                msg = "短信过长,请查看监控结果表base_db.data_monitor_result获取具体监控执行结果";
            }
            smsService.sendSms(msg, effectiveReceiver);
        }
    }

    public void packageJobExcuteResult(List<AccessJob> results, String jobType, String date, List<JobExcuteResult> jobResults) {
        for (AccessJob job : results) {
            JobExcuteResult jobExcuteResult = new JobExcuteResult();
            jobExcuteResult.setDataDate(date);
            jobExcuteResult.setJobType(jobType);
            jobExcuteResult.setExcuteStartTime(job.getBatchExecStart());
            jobExcuteResult.setExcuteEndTime(job.getBatchExecEnd());
            jobExcuteResult.setTaskId(job.getTaskId());
            switch (job.getBatchExecStatus()) {
                case 1: {
                    jobExcuteResult.setExcuteStatus("完成");
                }
                break;
                case 2: {
                    jobExcuteResult.setExcuteStatus("失败");
                }
                break;
                case 4: {
                    jobExcuteResult.setExcuteStatus("数据不一致");
                }
                break;
                default: {
                    jobExcuteResult.setExcuteStatus("错误的状态");
                }
            }
            jobExcuteResult.setSrcDataName(job.getSrcDataObjName());
            jobExcuteResult.setTargetDataName(job.getTargetDataObjName());
            jobResults.add(jobExcuteResult);
        }
    }
}
